package com.qf.blog.service.impl;

import com.qf.blog.commons.constants.SysConsts;
import com.qf.blog.commons.security.UserTokenThreadLocal;
import com.qf.blog.service.IPostScoreService;
import com.qf.blog.service.LikeService;
import com.qf.blog.vo.LikeVo;
import com.qf.blog.vo.UserToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.function.BiConsumer;

@Service
@Slf4j
public class LikeServiceImpl implements LikeService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IPostScoreService postScoreService;

    @Override
    public String getRedisKey(LikeVo likeVo) {
        Integer entityType = likeVo.getEntityType();
        Integer entityId = likeVo.getEntityId();
        switch (entityType) {
            case 1:
                return String.format(SysConsts.RedisKeys.USER_LIKE_KEY, SysConsts.POST, entityId);
            case 2:
                return String.format(SysConsts.RedisKeys.USER_LIKE_KEY, SysConsts.COMMENT, entityId);
            default:
                return null;
        }
    }

    public void change(LikeVo likeVo, BiConsumer<String, String> consumer) {
        String redisKey = getRedisKey(likeVo);
        String userId = likeVo.getUserId().toString();
        consumer.accept(redisKey, userId);
        Integer postId = likeVo.getPostId();
        if (likeVo.getEntityType().equals(1)) {
            log.info("点赞/取消点赞帖子id" + postId);
            postScoreService.addPostIdToRedis(postId);
        }
    }

    /**
     * 点赞
     *
     * @param likeVo
     * @author Zhendong Song
     * @time 2023/6/8 19:59
     **/
    @Override
    public void like(LikeVo likeVo) {
        SetOperations<String, String> setOperations = stringRedisTemplate.opsForSet();
        change(likeVo, setOperations::add);
        if (likeVo.getEntityType() == 1) {
            // 给帖子点赞需要计算帖子的分数
            postScoreService.addPostIdToRedis(likeVo.getEntityId());
        }
    }

    /**
     * 取消点赞
     *
     * @param likeVo
     * @author Zhendong Song
     * @time 2023/6/8 20:00
     **/
    @Override
    public void unlike(LikeVo likeVo) {
        SetOperations<String, String> setOperations = stringRedisTemplate.opsForSet();
        change(likeVo, setOperations::remove);
    }


    /**
     * 返回点赞实体的数量
     *
     * @param likeVo
     * @author Zhendong Song
     * @time 2023/6/8 20:03
     **/
    @Override
    public Long getLikeCount(LikeVo likeVo) {
        String redisKey = getRedisKey(likeVo);
        return stringRedisTemplate.opsForSet().size(redisKey);
    }

    @Override
    public boolean getLikeStatus(LikeVo likeVo) {
        UserToken userToken = UserTokenThreadLocal.get();
        if (userToken == null) {
            return false;
        }
        String redisKey = getRedisKey(likeVo);
        Integer userId = userToken.getUserId();
        // 判断当前用户是否已经点赞了
        return stringRedisTemplate.opsForSet().isMember(redisKey, userId.toString());
    }
}
